home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / copypix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-04  |  11.4 KB  |  436 lines

  1. /* $Id: copypix.c,v 3.8 1998/07/17 03:24:16 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: copypix.c,v $
  26.  * Revision 3.8  1998/07/17 03:24:16  brianp
  27.  * added Pixel.ScaleOrBiasRGBA field
  28.  *
  29.  * Revision 3.7  1998/05/31 23:50:36  brianp
  30.  * cleaned up a few Solaris compiler warnings
  31.  *
  32.  * Revision 3.6  1998/04/01 02:58:52  brianp
  33.  * applied Miklos Fazekas's 3-31-98 Macintosh changes
  34.  *
  35.  * Revision 3.5  1998/03/27 03:30:36  brianp
  36.  * fixed G++ warnings
  37.  *
  38.  * Revision 3.4  1998/02/15 01:31:41  brianp
  39.  * removed unused variables
  40.  *
  41.  * Revision 3.3  1998/02/08 20:22:14  brianp
  42.  * LOTS of clean-up and rewriting
  43.  *
  44.  * Revision 3.2  1998/02/04 00:33:45  brianp
  45.  * fixed a few cast problems for Amiga StormC compiler
  46.  *
  47.  * Revision 3.1  1998/02/01 22:16:34  brianp
  48.  * include different headers (zooming)
  49.  *
  50.  * Revision 3.0  1998/01/31 20:49:24  brianp
  51.  * initial rev
  52.  *
  53.  */
  54.  
  55.  
  56. #ifdef PC_HEADER
  57. #include "all.h"
  58. #else
  59. #include <string.h>
  60. #include "context.h"
  61. #include "copypix.h"
  62. #include "depth.h"
  63. #include "feedback.h"
  64. #include "macros.h"
  65. #include "pixel.h"
  66. #include "span.h"
  67. #include "stencil.h"
  68. #include "types.h"
  69. #include "zoom.h"
  70. #endif
  71.  
  72.  
  73.  
  74. static void copy_rgb_pixels( GLcontext* ctx,
  75.                  GLint srcx, GLint srcy, GLint width, GLint height,
  76.                  GLint destx, GLint desty )
  77. {
  78.    GLdepth zspan[MAX_WIDTH];
  79.    GLubyte rgba[MAX_WIDTH][4];
  80.    GLboolean quick_draw;
  81.    GLint sy, dy, stepy;
  82.    GLint i, j;
  83.    GLboolean setbuffer;
  84. #ifdef BUGFIX
  85.    GLubyte* saveAlpha;
  86. #endif
  87.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F;
  88.  
  89.    /* Determine if copy should be done bottom-to-top or top-to-bottom */
  90.    if (srcy<desty) {
  91.       /* top-down  max-to-min */
  92.       sy = srcy + height - 1;
  93.       dy = desty + height - 1;
  94.       stepy = -1;
  95.    }
  96.    else {
  97.       /* bottom-up  min-to-max */
  98.       sy = srcy;
  99.       dy = desty;
  100.       stepy = 1;
  101.    }
  102.  
  103.    if (ctx->Depth.Test) {
  104.       /* fill in array of z values */
  105.       GLint z = (GLint) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  106.       for (i=0;i<width;i++) {
  107.      zspan[i] = z;
  108.       }
  109.    }
  110.  
  111.    if (ctx->RasterMask==0 && !zoom
  112.        && destx>=0 && destx+width<=ctx->Buffer->Width) {
  113.       quick_draw = GL_TRUE;
  114.    }
  115.    else {
  116.       quick_draw = GL_FALSE;
  117.    }
  118. #ifdef BUGFIX
  119.    saveAlpha = ctx->Buffer->Alpha;
  120. #endif
  121.    /* If read and draw buffer are different we must do buffer switching */
  122.    setbuffer = ctx->Pixel.ReadBuffer!=ctx->Color.DrawBuffer;
  123.    for (j=0; j<height; j++, sy+=stepy, dy+=stepy) {
  124.       if (setbuffer) {
  125.      (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  126. #ifdef BUGFIX
  127.      if (ctx->Pixel.ReadBuffer == GL_FRONT)
  128.         ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  129.      else
  130.         ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  131. #endif
  132.       }
  133.       gl_read_rgba_span( ctx, width, srcx, sy, rgba );
  134.       if (ctx->Pixel.ScaleOrBiasRGBA) {
  135.      gl_scale_and_bias_rgba( ctx, width, rgba );
  136.       }
  137.       if (ctx->Pixel.MapColorFlag) {
  138.      gl_map_rgba( ctx, width, rgba );
  139.       }
  140.       if (setbuffer) {
  141.      (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  142. #ifdef BUGFIX
  143.      if (ctx->Color.DrawBuffer == GL_FRONT)
  144.         ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  145.      else
  146.         ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  147. #endif
  148.       }
  149.       if (quick_draw && dy>=0 && dy<ctx->Buffer->Height) {
  150. #ifndef __STORM__
  151.      (*ctx->Driver.WriteRGBASpan)( ctx, width, destx, dy, rgba, NULL );
  152. #else
  153.      (*ctx->Driver.WriteRGBASpan)( ctx, width, destx, dy, (CONST GLubyte(*)[4])rgba, NULL );
  154. #endif
  155.       }
  156.       else if (zoom) {
  157. #ifndef __STORM__
  158.      gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, rgba, desty);
  159. #else
  160.      gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, (CONST GLubyte(*)[4])rgba, desty);
  161. #endif
  162.       }
  163.       else {
  164.      gl_write_rgba_span( ctx, width, destx, dy, zspan, rgba, GL_BITMAP );
  165.       }
  166.    }
  167. #ifdef BUGFIX
  168.    ctx->Buffer->Alpha = saveAlpha;
  169. #endif
  170. }
  171.  
  172.  
  173.  
  174. static void copy_ci_pixels( GLcontext* ctx,
  175.                 GLint srcx, GLint srcy, GLint width, GLint height,
  176.                 GLint destx, GLint desty )
  177. {
  178.    GLdepth zspan[MAX_WIDTH];
  179.    GLint sy, dy, stepy;
  180.    GLint i, j;
  181.    GLboolean setbuffer;
  182.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F;
  183.    const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset;
  184.  
  185.    /* Determine if copy should be bottom-to-top or top-to-bottom */
  186.    if (srcy<desty) {
  187.       /* top-down  max-to-min */
  188.       sy = srcy + height - 1;
  189.       dy = desty + height - 1;
  190.       stepy = -1;
  191.    }
  192.    else {
  193.       /* bottom-up  min-to-max */
  194.       sy = srcy;
  195.       dy = desty;
  196.       stepy = 1;
  197.    }
  198.  
  199.    if (ctx->Depth.Test) {
  200.       /* fill in array of z values */
  201.       GLint z = (GLint) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  202.       for (i=0;i<width;i++) {
  203.      zspan[i] = z;
  204.       }
  205.    }
  206.  
  207.    /* If read and draw buffer are different we must do buffer switching */
  208.    setbuffer = ctx->Pixel.ReadBuffer!=ctx->Color.DrawBuffer;
  209.  
  210.    for (j=0; j<height; j++, sy+=stepy, dy+=stepy) {
  211.       GLuint indexes[MAX_WIDTH];
  212.       if (setbuffer) {
  213.      (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  214.       }
  215.       gl_read_index_span( ctx, width, srcx, sy, indexes );
  216.  
  217.       if (shift_or_offset) {
  218.      gl_shift_and_offset_ci( ctx, width, indexes );
  219.       }
  220.       if (ctx->Pixel.MapColorFlag) {
  221.      gl_map_ci( ctx, width, indexes );
  222.       }
  223.  
  224.       if (setbuffer) {
  225.      (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  226.       }
  227.       if (zoom) {
  228.      gl_write_zoomed_index_span( ctx, width, destx, dy, zspan, indexes, desty );
  229.       }
  230.       else {
  231.      gl_write_index_span( ctx, width, destx, dy, zspan, indexes, GL_BITMAP );
  232.       }
  233.    }
  234. }
  235.  
  236.  
  237.  
  238. /*
  239.  * TODO: Optimize!!!!
  240.  */
  241. static void copy_depth_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
  242.                    GLint width, GLint height,
  243.                    GLint destx, GLint desty )
  244. {
  245.    GLfloat depth[MAX_WIDTH];
  246.    GLdepth zspan[MAX_WIDTH];
  247.    GLuint indexes[MAX_WIDTH];
  248.    GLubyte rgba[MAX_WIDTH][4];
  249.    GLint sy, dy, stepy;
  250.    GLint i, j;
  251.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F;
  252.  
  253.    if (!ctx->Buffer->Depth) {
  254.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
  255.       return;
  256.    }
  257.  
  258.    /* Determine if copy should be bottom-to-top or top-to-bottom */
  259.    if (srcy<desty) {
  260.       /* top-down  max-to-min */
  261.       sy = srcy + height - 1;
  262.       dy = desty + height - 1;
  263.       stepy = -1;
  264.    }
  265.    else {
  266.       /* bottom-up  min-to-max */
  267.       sy = srcy;
  268.       dy = desty;
  269.       stepy = 1;
  270.    }
  271.  
  272.    /* setup colors or indexes */
  273.    if (ctx->Visual->RGBAflag) {
  274.       GLuint *rgba32 = (GLuint *) rgba;
  275.       GLuint color = *((GLuint *) ctx->Current.ByteColor);
  276.       for (i=0; i<width; i++) {
  277.      rgba32[i] = color;
  278.       }
  279.    }
  280.    else {
  281.       for (i=0;i<width;i++) {
  282.      indexes[i] = ctx->Current.Index;
  283.       }
  284.    }
  285.  
  286.    for (j=0; j<height; j++, sy+=stepy, dy+=stepy) {
  287.       (*ctx->Driver.ReadDepthSpanFloat)( ctx, width, srcx, sy, depth );
  288.  
  289.       for (i=0;i<width;i++) {
  290.      GLfloat d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
  291.      zspan[i] = (GLint) (CLAMP( d, 0.0F, 1.0F ) * DEPTH_SCALE);
  292.       }
  293.  
  294.       if (ctx->Visual->RGBAflag) {
  295.      if (zoom) {
  296. #ifndef __STORM__
  297.         gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, rgba, desty );
  298. #else
  299.         gl_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, (CONST GLubyte(*)[4])rgba, desty );
  300. #endif
  301.      }
  302.      else {
  303.         gl_write_rgba_span( ctx, width, destx, dy, zspan, rgba, GL_BITMAP);
  304.      }
  305.       }
  306.       else {
  307.      if (zoom) {
  308.         gl_write_zoomed_index_span( ctx, width, destx, dy,
  309.                     zspan, indexes, desty );
  310.      }
  311.      else {
  312.         gl_write_index_span( ctx, width, destx, dy,
  313.                  zspan, indexes, GL_BITMAP );
  314.      }
  315.       }
  316.    }
  317. }
  318.  
  319.  
  320.  
  321. static void copy_stencil_pixels( GLcontext* ctx, GLint srcx, GLint srcy,
  322.                  GLint width, GLint height,
  323.                  GLint destx, GLint desty )
  324. {
  325.    GLubyte stencil[MAX_WIDTH];
  326.    GLint sy, dy, stepy;
  327.    GLint j;
  328.    const GLboolean zoom = (ctx->Pixel.ZoomX!=1.0F || ctx->Pixel.ZoomY!=1.0F);
  329.    const GLboolean shift_or_offset = ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0;
  330.  
  331.    if (!ctx->Buffer->Stencil) {
  332.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
  333.       return;
  334.    }
  335.  
  336.    /* Determine if copy should be bottom-to-top or top-to-bottom */
  337.    if (srcy<desty) {
  338.       /* top-down  max-to-min */
  339.       sy = srcy + height - 1;
  340.       dy = desty + height - 1;
  341.       stepy = -1;
  342.    }
  343.    else {
  344.       /* bottom-up  min-to-max */
  345.       sy = srcy;
  346.       dy = desty;
  347.       stepy = 1;
  348.    }
  349.  
  350.    for (j=0; j<height; j++, sy+=stepy, dy+=stepy) {
  351.       gl_read_stencil_span( ctx, width, srcx, sy, stencil );
  352.  
  353.       if (shift_or_offset) {
  354.      gl_shift_and_offset_stencil( ctx, width, stencil );
  355.       }
  356.       if (ctx->Pixel.MapStencilFlag) {
  357.      gl_map_stencil( ctx, width, stencil );
  358.       }
  359.  
  360.       if (zoom) {
  361.      gl_write_zoomed_stencil_span( ctx, width, destx, dy, stencil, desty );
  362.       }
  363.       else {
  364.      gl_write_stencil_span( ctx, width, destx, dy, stencil );
  365.       }
  366.    }
  367. }
  368.  
  369.  
  370.  
  371.  
  372. void gl_CopyPixels( GLcontext* ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height,
  373.             GLenum type )
  374. {
  375.    GLint destx, desty;
  376.  
  377.    if (INSIDE_BEGIN_END(ctx)) {
  378.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
  379.       return;
  380.    }
  381.  
  382.    if (width<0 || height<0) {
  383.       gl_error( ctx, GL_INVALID_VALUE, "glCopyPixels" );
  384.       return;
  385.    }
  386.  
  387.    if (ctx->NewState) {
  388.       gl_update_state(ctx);
  389.    }
  390.  
  391.    if (ctx->RenderMode==GL_RENDER) {
  392.       /* Destination of copy: */
  393.       if (!ctx->Current.RasterPosValid) {
  394.      return;
  395.       }
  396.       destx = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  397.       desty = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  398.  
  399.       if (type==GL_COLOR && ctx->Visual->RGBAflag) {
  400.      copy_rgb_pixels( ctx, srcx, srcy, width, height, destx, desty );
  401.       }
  402.       else if (type==GL_COLOR && !ctx->Visual->RGBAflag) {
  403.      copy_ci_pixels( ctx, srcx, srcy, width, height, destx, desty );
  404.       }
  405.       else if (type==GL_DEPTH) {
  406.      copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );
  407.       }
  408.       else if (type==GL_STENCIL) {
  409.      copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );
  410.       }
  411.       else {
  412.      gl_error( ctx, GL_INVALID_ENUM, "glCopyPixels" );
  413.       }
  414.    }
  415.    else if (ctx->RenderMode==GL_FEEDBACK) {
  416.       GLfloat color[4];
  417.       color[0] = (GLfloat) ctx->Current.ByteColor[0] / 255.0;
  418.       color[1] = (GLfloat) ctx->Current.ByteColor[1] / 255.0;
  419.       color[2] = (GLfloat) ctx->Current.ByteColor[2] / 255.0;
  420.       color[3] = (GLfloat) ctx->Current.ByteColor[3] / 255.0;
  421.       FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN );
  422.       gl_feedback_vertex( ctx, ctx->Current.RasterPos[0],
  423.               ctx->Current.RasterPos[1],
  424.               ctx->Current.RasterPos[2],
  425.               ctx->Current.RasterPos[3],
  426.               color, ctx->Current.Index,
  427.               ctx->Current.TexCoord );
  428.    }
  429.    else if (ctx->RenderMode==GL_SELECT) {
  430.       gl_update_hitflag( ctx, ctx->Current.RasterPos[2] );
  431.    }
  432.  
  433. }
  434.  
  435.  
  436.